#! /usr/bin/env node
"use strict";
const path = require("path");
const fs = require("fs");
const axios = require("axios");
const urlJoin = require("url-join");
const semver = require("semver");

function _getNpmInfo(npmName, registry) {
  if (!npmName) return null;
  const _registry = "https://registry.npmjs.org";
  const npmInfoUrl = urlJoin(_registry, npmName);
  return axios
    .get(npmInfoUrl)
    .then((response) => {
      if (response.status === 200) {
        return response.data;
      }
      return null;
    })
    .catch((err) => {
      return Promise.reject(err);
    });
}

async function getNpmVersions(npmName, registry) {
  const data = await _getNpmInfo(npmName, registry);
  return data ? Object.keys(data.versions) : [];
}

function getSemverVersion(baseVersion, versions = []) {
  return versions
    .filter((version) => semver.satisfies(version, `^${baseVersion}`))
    .sort((a, b) => {
      return semver.gt(b, a);
    });
}

async function getNpmSemverVersion(baseVersion, npmName, registry) {
  const versions = await getNpmVersions(npmName, registry);
  const newVersions = getSemverVersion(baseVersion, versions);
  console.log("newVersions", newVersions);
  if (newVersions && newVersions.length > 0) return newVersions[0];
}

// function getDefaultRegistry(isOriginal = true) {
//   return isOriginal
//     ? 'https://registry.npmjs.org'
//     : 'https://registry.npm.taobao.org'
// }

async function getNpmLatestVersion(npmName, registry) {
  let versions = await getNpmVersions(npmName, registry);
  if (versions) {
    const newVersions = versions.sort((a, b) => (semver.gt(b, a) ? 1 : -1));
    return newVersions[0];
  }
  return null;
}

function formatPath(p) {
  //path /Users/xch/Documents/全栈/medlog-cli-dev/commands/init/lib/index.js
  // 将winows的路径中\替换成/
  if (p && typeof p === "string") {
    return p.sep === "/" ? p : p.replace(/\\/g, "/");
  }
  return p;
}

function exec(command, args, options) {
  const win32 = process.platform === "win32";
  const cmd = win32 ? "cmd" : command;
  const cmdArgs = win32 ? ["/c"].concat(command, args) : args;
  return require("child_process").spawn(cmd, cmdArgs, options || {});
}

function execAsync(command, args, options) {
  return new Promise((resolve, reject) => {
    const p = exec(command, args, options);
    p.on("error", (e) => {
      reject(e);
    });
    p.on("exit", (c) => {
      resolve(c);
    });
  });
}

/**
 * 判断文件夹是否为空
 * @param {项目目录} localPath
 * @returns
 */
function isDirEmpty(localPath) {
  let fileList = fs.readdirSync(localPath);
  // 文件过滤逻辑
  fileList = fileList.filter(
    (file) => !file.startsWith(".") && ["node_modules"].indexOf(file) < 0
  );
  return !fileList || fileList.length <= 0;
}

/**
 * 项目名称命名规则
 * 规则一：输入的首字符为英文字符
 * 规则二：尾字符必须为英文或数字
 * 规则三：字符仅允许-和_两种
 * \w=a-zA_Z0-9_
 * @param {*} v
 * @returns
 */
function isValidName(v) {
  return /^[a-zA-Z]+([-][a-zA-Z][a-zA-Z0-9]*|[_][a-zA-Z][a-zA-Z0-9]*|[a-zA-Z0-9])*$/.test(
    v
  );
}

function spinnerStart(msg, spinnerString = "|/-\\") {
  const Spinner = require("cli-spinner").Spinner;
  const spinner = new Spinner(msg + " %s");
  spinner.setSpinnerString(spinnerString);
  spinner.start();
  return spinner;
}
function sleep(timeout = 1000) {
  return new Promise((resolve) => setTimeout(resolve, timeout));
}

module.exports = {
  formatPath,
  getNpmSemverVersion,
  // getDefaultRegistry,
  getNpmLatestVersion,
  getSemverVersion,
  exec,
  isDirEmpty,
  isValidName,
  spinnerStart,
  sleep,
  execAsync,
};
